@use 'sass:math';
@use '@material/animation/index' as animation;
@use '@material/elevation/index' as elevation;
@use '@material/theme/index' as theme;
@use '@material/feature-targeting/index' as feature-targeting;
@use '@material/typography/index' as typography;
@use '@material/ripple/ripple' as ripple;
@use '@smui/paper/mixins' as paper;

$ripple-target: '.smui-accordion__header__ripple';
$panel-padding: 16px 24px !default;
$open-margin: 1rem;
$extend-width: 10px;
$transition-duration: 0.2s;
$content-transition-duration: 0.3s;
$divider-color-on-light-bg: rgba(0, 0, 0, 0.12) !default;
$divider-color-on-dark-bg: rgba(255, 255, 255, 0.2) !default;

@mixin core-styles($query: feature-targeting.all()) {
  $feat-color: feature-targeting.create-target($query, color);
  $feat-animation: feature-targeting.create-target($query, animation);
  $feat-structure: feature-targeting.create-target($query, structure);

  @include ripple.common($query);

  .smui-accordion {
    display: block;
    position: relative;
    z-index: 0;

    &.smui-accordion--with-open-dialog {
      z-index: auto;
    }

    .smui-accordion__panel {
      @include ripple.surface($query: $query, $ripple-target: $ripple-target);
      @include ripple.radius-bounded(
        $query: $query,
        $ripple-target: $ripple-target
      );

      position: relative;
      padding: 0;
      margin-top: 0;
      margin-bottom: 0;
      transition: animation.standard(margin-top, $transition-duration),
        animation.standard(margin-bottom, $transition-duration);

      &.smui-accordion__panel--extend {
        // Adding width, left, and box-shadow to animate the scaling and
        // elevation change as well.
        transition: animation.standard(width, $transition-duration),
          animation.standard(left, $transition-duration),
          animation.standard(box-shadow, $transition-duration),
          animation.standard(margin-top, $transition-duration),
          animation.standard(margin-bottom, $transition-duration);
        width: 100%;
        left: 0;

        &.smui-accordion__panel--open {
          width: calc(100% + $extend-width);
          left: math.div($extend-width, 2) * -1;
        }
      }

      &.smui-accordion__panel--raised,
      &.smui-paper--unelevated {
        // Create a separator line.
        border-top-width: 1px;
        border-top-style: solid;
        border-top-color: if(
          theme.tone(theme.$background) == 'dark',
          $divider-color-on-dark-bg,
          $divider-color-on-light-bg
        );
      }

      // The shadow needs to go on a :before element so it doesn't cover the
      // previous panel.
      // Credit: https://blog.dudak.me/2014/css-shadows-under-adjacent-elements/
      &.smui-paper.smui-accordion__panel--raised {
        z-index: auto;
        will-change: auto;

        &::before {
          content: '';
          position: absolute;
          top: 0;
          bottom: 0;
          left: 0;
          right: 0;
          z-index: -1;
        }
      }
      &.smui-accordion__panel--raised {
        @include panel-elevation($query: $query);

        &.smui-paper--color-primary {
          @include panel-elevation(primary, $query: $query);
        }

        &.smui-paper--color-secondary {
          @include panel-elevation(secondary, $query: $query);
        }
      }

      &.smui-accordion__panel--raised,
      &.smui-paper--unelevated {
        // Hide the separator line.

        &:first-child {
          border-top-width: 0;
        }

        &:last-child {
          border-top-left-radius: 0;
          border-top-right-radius: 0;
        }

        &.smui-accordion__panel--open,
        &.smui-accordion__panel--open + .smui-accordion__panel {
          border-top-width: 0;
        }
      }

      // Hide top border on not first child outlined panels.
      &.smui-paper--outlined {
        &:nth-child(1n + 2) {
          border-top-width: 0;
        }

        &.smui-accordion__panel--open,
        &.smui-accordion__panel--open + .smui-accordion__panel {
          border-top-width: 1px;
        }
      }

      // Round the corners of the shadow pseudo-element too.
      &.smui-paper--rounded::before {
        @include paper.shape-radius(medium, $query: $query);
      }

      // Square off the corners of all but the first and last panels.
      &:first-child:not(:last-child),
      &:first-child:not(:last-child)::before {
        border-bottom-left-radius: 0;
        border-bottom-right-radius: 0;
      }
      &:last-child:not(:first-child),
      &:last-child:not(:first-child)::before {
        border-top-left-radius: 0;
        border-top-right-radius: 0;
      }
      &:not(:first-child, :last-child),
      &:not(:first-child, :last-child)::before {
        border-radius: 0;
      }

      & > .smui-accordion__header {
        @include typography.typography(body1);

        display: flex;
        flex-wrap: wrap;
        cursor: pointer;

        .smui-accordion__header__title {
          padding: $panel-padding;
          flex-grow: 1;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;

          &.smui-accordion__header__title--with-description {
            flex-basis: 30%;
            max-width: 280px;
            box-sizing: border-box;
            padding-inline-end: 0;
          }
        }

        .smui-accordion__header__description {
          opacity: 0.48;
          padding: $panel-padding;
          flex-basis: 0;
          flex-grow: 1;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }

        .smui-accordion__header__icon {
          align-self: center;
          flex-shrink: 1;
          margin: $panel-padding;
          margin-top: 0;
          margin-bottom: 0;
          margin-inline-start: 0;
        }

        #{$ripple-target} {
          @include feature-targeting.targets($feat-structure) {
            position: absolute;
            // Ripple needs content-box as the box sizing and box-sizing: border-box
            // is often set as a default, so we override that here.
            box-sizing: content-box;
            width: 100%;
            height: 100%;
            overflow: hidden;
            z-index: 0;
            pointer-events: none;
          }
        }
      }

      &.smui-accordion__panel--disabled,
      &.smui-accordion__panel--non-interactive {
        & > .smui-accordion__header {
          cursor: initial;
        }
      }

      &.smui-accordion__panel--disabled {
        & > .smui-accordion__header,
        & > .smui-paper__content {
          opacity: 0.38;
        }
      }

      & > .smui-paper__content {
        overflow: hidden;
        transition: animation.standard(height, $content-transition-duration),
          animation.standard(padding, $content-transition-duration);
        box-sizing: border-box;
        height: 0;
        padding: $panel-padding;
        padding-top: 0;
        padding-bottom: 0;

        &.smui-accordion__content--no-transition {
          transition: none;
        }

        &.smui-accordion__content--force-open {
          height: auto;
          padding: $panel-padding;
        }
      }

      &.smui-accordion__panel--opened > .smui-paper__content {
        overflow: visible;
      }

      &.smui-accordion__panel--open {
        margin-top: $open-margin;
        margin-bottom: $open-margin;

        &:first-child {
          margin-top: 0;
        }

        &:last-child {
          margin-bottom: 0;
        }

        & > .smui-paper__content {
          height: auto;
          padding: $panel-padding;
        }
      }
    }
  }
}

@mixin panel-elevation(
  $color: elevation.$baseline-color,
  $query: feature-targeting.all()
) {
  @for $i from 0 through 24 {
    &.smui-accordion__panel--elevation-z#{$i}::before {
      @include elevation.elevation($i, $color, $query: $query);
    }
  }
}
